package com.qqtech.qquan.mall.service;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;
import com.google.common.primitives.Ints;
import com.qqtech.core.common.exception.OrderException;
import com.qqtech.core.common.util.StringUtil;
import com.qqtech.core.common.util.TimeUtil;
import com.qqtech.core.frame.dao.BaseDao;
import com.qqtech.core.frame.model.Result;
import com.qqtech.core.frame.service.BaseServiceImpl;
import com.qqtech.qquan.coupon.enums.CouponUserStatusDictEnum;
import com.qqtech.qquan.coupon.model.CouponUserVo;
import com.qqtech.qquan.coupon.service.CouponBaseService;
import com.qqtech.qquan.coupon.service.CouponUserService;
import com.qqtech.qquan.mall.cache.MallSysParamCache;
import com.qqtech.qquan.mall.dao.MallCartDao;
import com.qqtech.qquan.mall.dao.MallOrderDao;
import com.qqtech.qquan.mall.dao.MallProductDao;
import com.qqtech.qquan.mall.dao.MallProductSpecDao;
import com.qqtech.qquan.mall.dao.MallSupplierDao;
import com.qqtech.qquan.mall.enums.MallProductSpecStatusDictEnum;
import com.qqtech.qquan.mall.enums.MallProductStatusDictEnum;
import com.qqtech.qquan.mall.enums.MallSupplierTypeDictEnum;
import com.qqtech.qquan.mall.model.MallCart;
import com.qqtech.qquan.mall.model.MallOrder;
import com.qqtech.qquan.mall.model.MallOrderVo;
import com.qqtech.qquan.mall.model.MallProduct;
import com.qqtech.qquan.mall.model.MallProductSpec;
import com.qqtech.qquan.mall.model.MallSupplier;
import com.qqtech.qquan.order.cache.OrderSysParamCache;
import com.qqtech.qquan.order.dao.OrderBaseDao;
import com.qqtech.qquan.order.enums.OrderBaseOrderTypeDictEnum;
import com.qqtech.qquan.order.enums.OrderBaseSubsidyTypeDictEnum;
import com.qqtech.qquan.order.model.OrderBase;
import com.qqtech.qquan.order.model.OrderCouponVo;
import com.qqtech.qquan.order.model.OrderDelivery;
import com.qqtech.qquan.order.model.OrderItem;
import com.qqtech.qquan.order.service.OrderCouponService;
import com.qqtech.qquan.order.service.OrderHandleService;
import com.qqtech.qquan.order.service.OrderItemService;
import com.qqtech.qquan.push.service.PushBizzService;
import com.qqtech.qquan.sales.dao.SalesBaseDao;
import com.qqtech.qquan.sales.model.SalesBaseVo;

@Service
public class MallOrderServiceImpl extends BaseServiceImpl<MallOrder> implements MallOrderService {
	public static final Logger log = LoggerFactory.getLogger(MallOrderServiceImpl.class);

	@Resource
	private MallOrderDao mallOrderDao;

	@Resource
	private MallProductDao mallProductDao;

	@Resource
	private MallProductSpecDao mallProductSpecDao;

	@Resource
	private OrderBaseDao orderBaseDao;

	@Resource
	private OrderItemService orderItemService;

	@Resource
	private MallCartDao mallCartDao;

	@Resource
	private OrderHandleService orderHandleService;

	@Resource
	private MallProductService mallProductService;

	@Resource
	private MallProductSpecService mallProductSpecService;

	@Resource
	private OrderSysParamCache orderSysParamCache;
	@Resource
	private PushBizzService pushBizzService;

	@Resource
	private MallSysParamCache mallSysParamCache;

	@Resource
	private SalesBaseDao salesBaseDao;

	@Resource
	private CouponBaseService couponBaseService;
	@Resource
	private CouponUserService couponUserService;
	@Resource
	private OrderCouponService orderCouponService;
	@Resource
	private MallSupplierDao mallSupplierDao;

	@Override
	protected BaseDao<MallOrder> getBaseDao() {
		return mallOrderDao;
	}

	@Override
	public MallOrder getByOrderNo(java.lang.String orderNo) {
		return mallOrderDao.getByOrderNo(orderNo);
	}

	@Override
	public Result handleSaveOrder(OrderBase orderBase, OrderDelivery orderDelivery, List<OrderItem> orderItems,MallOrderVo mallOrderVo)
			throws OrderException {
		Result result = new Result();
		// 订单明细
		Integer shopId = orderBase.getShopId();
		//是否外部供应商
		Integer isExternal = MallSupplierTypeDictEnum.EXTERNAL.getCode();
		int i = 0;
		for (OrderItem orderItem : orderItems) {
			if (orderItem.getProductId() != null) {
				// 重新加载商品数据，进行订单结算统计
				MallProductSpec spec = mallProductSpecDao.getById(orderItem.getProductId()); // 规格详情
				MallProduct productItem = mallProductDao.getById(spec.getProductId()); // 产品详情
				if (productItem != null && spec != null) {
					if (spec.getStatus().intValue() == MallProductSpecStatusDictEnum.DELETE.getCode()) {
						result.addErr(productItem.getName()+"的"+spec.getColor() + spec.getSpecName()+"已经下架。");
					}
					if (spec.getStock().intValue() <= 0) {
						result.addErr(productItem.getName()+"的"+spec.getColor() + spec.getSpecName()+"库存不足。");
					}
					if (productItem.getStatus().intValue() != MallProductStatusDictEnum.ONSHELF.getCode()) {
						result.addErr(productItem.getName()+"已经下架。");
					}
					if(i == 0 && productItem.getSupplierId() != null){
						MallSupplier supplier = mallSupplierDao.getById(productItem.getSupplierId());
						if (supplier != null
								&& supplier.getType().intValue() == MallSupplierTypeDictEnum.LOCAL
										.getCode()) {
							isExternal =  MallSupplierTypeDictEnum.LOCAL.getCode();
						}
						orderBase.setIsExternal(isExternal);
					}
					if(orderBase.getOrderType().intValue() == OrderBaseOrderTypeDictEnum.QUANMALL.getCode()){
						orderItem.setSupplierId(productItem.getSupplierId());//商城
					}else{
						orderItem.setSupplierId(shopId);//圈商
					}
					orderItem.setName(productItem.getName());
					orderItem.setPrice(spec.getPrice()); // 价格
					orderItem.setProductSpecName(spec.getColor() + spec.getSpecName()); // 订单详情规格描述=颜色+规格
					if (StringUtil.isNotBlank(productItem.getImg())) {
						String[] imgs = productItem.getImg().split(";");
						orderItem.setImg(imgs[0]);
					}
					BigDecimal tempPriceTotal = orderItem.getPrice().multiply(new BigDecimal(orderItem.getQuntity()));
					orderBase.setTotal(orderBase.getTotal().add(tempPriceTotal)); // 商品总额
				}
			}
			i++;
		}
		if (!result.checkForm()) {
			return result;
		}
		if (orderItems != null && orderItems.size() > 1) {
			orderBase.setTitle(orderItems.get(0).getName() + "等");
		} else {
			orderBase.setTitle(orderItems.get(0).getName());
		}
		orderBase.setImg(orderItems.get(0).getImg());
		orderBase.setOriginalTotal(orderBase.getTotal());
		//促销活动扣减
		orderBase.setSubsidyType(OrderBaseSubsidyTypeDictEnum.NONE.getCode());
		orderBase.setSubsidy(BigDecimal.ZERO);
		if (shopId != null && shopId != 0) {
			SalesBaseVo sales = salesBaseDao.getByShopId(shopId);
			if (sales != null && orderBase.getTotal().compareTo(sales.getRequirement()) >= 0) {
				// 总额减优惠金额
				BigDecimal salesPrice = orderBase.getTotal().subtract(sales.getSubsidy());
				orderBase.setTotal(salesPrice);
				orderBase.setSalesId(sales.getId().toString());
				orderBase.setSubsidyType(sales.getSubsidyType());
				orderBase.setSubsidy(sales.getSubsidy());
			}
		}
		//优惠券扣减
		if(mallOrderVo.getTotalMinu() != null){
			BigDecimal total = orderBase.getTotal().subtract(mallOrderVo.getTotalMinu());//减去优惠价格
			if(total.compareTo(BigDecimal.ZERO)==-1){
				orderBase.setTotal(BigDecimal.ZERO);
			}else{
				orderBase.setTotal(total);
			}
		}
		//加入配送费
		if(orderDelivery.getFreight() != null && orderDelivery.getFreight().compareTo(BigDecimal.ZERO) != -1){
			orderBase.setTotal(orderBase.getTotal().add(orderDelivery.getFreight())); // 订单总额	
		}
		// 公共订单
		result = orderHandleService.createOrder(orderBase, orderDelivery, orderItems);
		String orderNo = result.get("orderNo").toString();
		if(null != mallOrderVo.getOrderCouponList() && mallOrderVo.getOrderCouponList().size() > 0){//使用了优惠卷
			for (OrderCouponVo orderCouponVo : mallOrderVo.getOrderCouponList()) {
				if(null!=orderCouponVo.getCouponUserIds()&&orderCouponVo.getCouponUserIds().size()>0){
					for (Integer couponUserId : orderCouponVo.getCouponUserIds()) {
						CouponUserVo couponUserVo=couponUserService.getById(couponUserId);
						if(null==couponUserVo||couponUserVo.getStatus()!=CouponUserStatusDictEnum.NOT_USED.getCode()){//优惠卷有效
							throw new OrderException("优惠券使用有误。");
						}
					}
				}
				orderCouponVo.setOrderNo(orderNo);
				int orderCouponId=orderCouponService.insert(orderCouponVo);
				if(null!=orderCouponVo.getCouponUserIds()&&orderCouponVo.getCouponUserIds().size()>0){
					for (Integer couponUserId : orderCouponVo.getCouponUserIds()) {
						CouponUserVo couponUserVo=couponUserService.getById(couponUserId);
						couponUserVo.setOrderCouponId(orderCouponId);
						couponUserVo.setStatus(CouponUserStatusDictEnum.BE_USED.getCode());
						couponUserService.updateById(couponUserVo);
					}
				}
			}
		}
		// 商城订单
		MallOrder mallOrder = new MallOrder();
		mallOrder.setOrderNo(orderNo);
		mallOrder.setUpdAt(TimeUtil.now());
		mallOrder.setNewAt(TimeUtil.now());
		mallOrderDao.insert(mallOrder);
		// 减少库存量
		reduceStock(orderItems);
		// 购物车移除TODO
		removeMallCart(orderBase.getBuyerId(), orderItems);
		pushBizzService.orderSelected(orderNo);
		return result;
	}

	/**
	 * 减少库存量
	 * 
	 */
	private void reduceStock(List<OrderItem> orderItems) throws OrderException {

		// 注意： by xionglie.qu at 2015-08-14
		// 为了避免更新死锁问题，
		// 必须对mallOrderItems进行排序后，再执行库存量更新操作
		Comparator<OrderItem> comparator = new Comparator<OrderItem>() {
			@Override
			public int compare(OrderItem o1, OrderItem o2) {
				return Ints.compare(o1.getProductId(), o1.getProductId());
			}
		};

		List<OrderItem> tmpItems = Lists.newArrayList(orderItems);
		Collections.sort(tmpItems, comparator);
		for (OrderItem item : orderItems) {
			// int productId = item.getProductId();
			int productSpecId = item.getProductId();
			int quantity = item.getQuntity();
			if (quantity <= 0) {
				throw new OrderException("商品购买数量必须大于0");
			}
			// int row = mallProductDao.reduceStock(productId, quantity);
			int row = mallProductSpecDao.reduceStock(productSpecId, quantity);
			if (row <= 0) {
				String productName = item.getName();
				throw new OrderException("商品【" + productName + "】的库存量不足");
			}
		}
	}

	/**
	 * 移除购物车商品
	 * 
	 */
	private void removeMallCart(Integer userId, List<OrderItem> orderItems) {
		for (OrderItem item : orderItems) {
			MallCart mallCart = new MallCart();
			mallCart.setCreatorId(userId);
			mallCart.setProductSpecId(item.getProductId());// 规格ID
			mallCartDao.delete(mallCart);
		}
	}

	@Override
	public String getAutoExpireTime(String key) {
		return orderSysParamCache.get(key);
	}

	@Override
	public Result handleCancelOrder(String orderNo) throws OrderException {
		Result result = new Result();
		// 公共取消订单
		result = orderHandleService.buyerCancel(orderNo);
		// 释放库存
		returnProductStock(orderNo);
		return result;
	}

	private void returnProductStock(String orderNo) {
		List<OrderItem> orderItems = orderItemService.findByOrderNo(orderNo);
		if (orderItems != null && orderItems.size() > 0) {
			for (OrderItem item : orderItems) {
				// int productId = item.getProductId();
				int specId = item.getProductId();
				int quantity = item.getQuntity();
				// mallProductService.handleReturnStock(productId, quantity);
				mallProductSpecService.handleReturnStock(specId, quantity);
			}
		}
	}

	@Override
	public String getDistributionX(String key) {
		return mallSysParamCache.get(key);
	}

	@Override
	public String getDistributionY(String key) {
		return mallSysParamCache.get(key);
	}

	@Override
	public String getDistributionRadius(String key) {
		return mallSysParamCache.get(key);
	}
	
	@Override
	public String getFreeDeliverValue(String key) {
		return mallSysParamCache.get(key);
	}

	@Override
	public String getMallHasOpenCommunityValue(String key) {
		return mallSysParamCache.get(key);
	}

	@Override
	public String getFreight(String key) {
		return mallSysParamCache.get(key);
	}

}